package com.sheng.project.demo.process;

import com.sheng.project.demo.utils.Sm2Util;
import com.sheng.project.demo.utils.Sm3Util;
import com.sheng.project.demo.utils.Sm4Util;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.UUID;

public class Encrypt {

    /**
     * hexPk:中行给的公钥
     * plainText：需要加密的字符串
     * return：加密后的经过hex的字符串
     */
    public static String encryptBySm2(String hexPublicKey, String plainText) {
        String X = hexPublicKey.substring(0, 64);
        String Y = hexPublicKey.substring(64);
        byte[] bytesData = plainText.getBytes();
        PublicKey pk = Sm2Util.getPublickeyFromXY(new BigInteger(X, 16), new BigInteger(Y, 16));
        byte[] bytes = Sm2Util.sm2Encrypt(bytesData, pk);
        return Hex.toHexString(bytes).substring(2);
    }

    public static void main(String[] args) {
        HashMap<String, String> data = new HashMap<String, String>();
        String plainText =
                "{\"respHeader\":{\"retCode\":\"0\",\"traceSerial\":\"788646546\",\"traceDate\":\"20220215\",\"traceTime\":\"161800\",\"retMsg\":\"成功\"}}";
        data.put("plainText", plainText);
        //        test02 对应的私钥d：32899081861859350481893304079131085995435639230432313207376002535134551573452
        data.put("sm2PublicKey",
                "661AFC402173927BE1413DE9F09187A5C168EFCED114D7D0CC46F9C190B9F2E6CA03B8D2D1292FAEC945D70A322A1E7F343BDC9958B6ECA65D50FF767594F32A");
        System.out.println(new Encrypt().process(data));
    }

    /**
     * 加密过程
     * 1.sm4对原数据进行加密  sm4秘钥+加密后的数据
     * 2.sm3对原始数据进行hash  hash后的数据
     * 3.sm2对sm4秘钥进行加密
     */
    public HashMap<String, String> process(HashMap<String, String> data) {
        //1.sm4加密
        try {
            String sm4Key = UUID.randomUUID().toString().replace("-", "");
            String body = data.get("plainText");
            String publicKey = data.get("sm2PublicKey");
            String sm4Cipher = Sm4Util.sm4Encrypt(sm4Key, body);

            String sm3Cipher = Sm3Util.encrypt(body);
            String sm2HexCipher = encryptBySm2(publicKey, sm4Key);
            HashMap<String, String> res = new HashMap<String, String>();
            res.put("skey", sm2HexCipher);
            res.put("signature", sm3Cipher);
            res.put("body", sm4Cipher);
            return res;
        } catch (Exception e) {
            System.out.println("加密失败");
            e.printStackTrace();
        }
        return null;
    }
}
